Skip to content

feat(events): add WebSocketConnectionContext helper for APIGatewayV2WebSocketEvent (#273)#606

Open
ramanathan1504 wants to merge 2 commits into
aws:mainfrom
ramanathan1504:issue-273-websocket-session-context
Open

feat(events): add WebSocketConnectionContext helper for APIGatewayV2WebSocketEvent (#273)#606
ramanathan1504 wants to merge 2 commits into
aws:mainfrom
ramanathan1504:issue-273-websocket-session-context

Conversation

@ramanathan1504
Copy link
Copy Markdown

This change addresses #273 by adding a session-like, Lambda-safe connection context for API Gateway WebSocket events.

What changed

  • Added WebSocketConnectionContext to APIGatewayV2WebSocketEvent in aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/APIGatewayV2WebSocketEvent.java
  • Added convenience accessors:
    • APIGatewayV2WebSocketEvent#getConnectionContext()
    • APIGatewayV2WebSocketEvent.RequestContext#getConnectionContext()
  • Added getManagementApiEndpoint() to build https://{domainName}/{stage} for API Gateway Management API usage
  • Added null/empty fallback behavior for endpoint parts (domainName, stage)
  • Added tests in aws-lambda-java-events/src/test/java/com/amazonaws/services/lambda/runtime/events/APIGatewayV2WebSocketEventTest.java
  • Documented usage and null-safe handling in aws-lambda-java-events/README.md
  • Added release note entry in aws-lambda-java-events/RELEASE.CHANGELOG.md

Why

AWS Lambda WebSocket events do not provide a native Java WebSocketSession. This helper provides a lightweight session-like object built from event metadata (connectionId, domainName, stage) so handlers can easily pass one context object through their business logic.

Backward compatibility

  • Non-breaking: existing event fields and getters remain unchanged.
  • Existing code using requestContext.getConnectionId() continues to work.
  • New behavior is additive only.

Error handling / fallback

  • getConnectionContext() returns null when requestContext or connectionId is missing.
  • getManagementApiEndpoint() returns null when domainName or stage is missing/empty.
  • No new exceptions introduced.

@ramanathan1504 ramanathan1504 force-pushed the issue-273-websocket-session-context branch 3 times, most recently from 8cc24e7 to e2f1a0d Compare May 19, 2026 19:10
@darklight3it
Copy link
Copy Markdown
Contributor

Hello @ramanathan1504, thanks for your contribution, any help is appreciated ❤️

Before diving into implementation details, I'd love to understand the use case better and make sure we're solving the right problem.

Every class in aws-lambda-java-events maps directly to a field or structure in an actual AWS service payload. WebSocketConnectionContext would be the first derived/computed object in the library, it doesn't correspond to anything in the API Gateway WebSocket schema.

Issue #273 asks for a WebSocketSession, which makes sense from a Spring/Jakarta EE perspective. But in Lambda, API Gateway owns the connection and Lambda is invoked once per message. Exposing this kind of object in an official AWS library could mislead users into thinking the runtime holds the connection the way Jakarta EE or Spring WebSocket do.

Were you thinking about Lambda Managed Instances and their multi-concurrency model as a use case here?

Besides that, the example provided in the README looks to me functionally identical to the one using requestContext directly.

using WebSocketConnectionContext

WebSocketConnectionContext connection = event.getConnectionContext();
if (connection != null) {
    String connectionId = connection.getConnectionId();
    String endpoint = connection.getManagementApiEndpoint();
}

using RequestContext

var rc = event.getRequestContext();
if (rc != null && rc.getConnectionId() != null) {
    String connectionId = rc.getConnectionId();
    String endpoint = "https://" + rc.getDomainName() + "/" + rc.getStage();
}

The only saving is the URL concatenation. Could you share a scenario where this meaningfully reduces the complexity for the end user?

Thanks again for your time!

@ramanathan1504
Copy link
Copy Markdown
Author

@darklight3it

Thanks for the detailed feedback.

My intention was not to model a persistent runtime-managed WebSocket session like Spring/Jakarta EE, but to provide a lightweight convenience abstraction around commonly grouped connection metadata already present in the payload.

In many Lambda WebSocket handlers, developers repeatedly reconstruct:

  • connectionId
  • management endpoint URL
  • domain/stage validation

This logic often gets duplicated across handlers/services and can become error-prone.

That said, I understand the concern about keeping aws-lambda-java-events strictly schema-aligned.

An alternative could be:

  • adding only helper methods directly on RequestContext
  • or exposing only getManagementApiEndpoint()
    without introducing a separate derived object.

Happy to adapt the PR direction based on what best fits the library design principles.

@ramanathan1504 ramanathan1504 force-pushed the issue-273-websocket-session-context branch from e4a52ae to 2ecc03f Compare May 25, 2026 18:27
@darklight3it
Copy link
Copy Markdown
Contributor

Hey @ramanathan1504,

Thanks for the answer. Reading through your comment I'm still not convinced that this change should be included in the events library for the following reasons:

  1. I don't think the "error-prone" concern applies here — domainName, stage, and connectionId are structurally required for a WebSocket API to function. There's no valid deployment without a domain and stage, and no event without a connectionId. In practice these fields are always populated, so there's no meaningful validation logic to centralize.

  2. If a team finds themselves building the endpoint URL across multiple places, a one-line utility method in their own codebase handles it. That gives them full control and doesn't add surface area to a shared library that is widely used and for which any change can be breaking.

More broadly, adding any derived/computed method to an event class would be a first for this library. Even a slim getManagementApiEndpoint() on RequestContext sets a precedent that makes it hard to refuse similar utility methods on other event classes in the future, and can undermine efforts to document and enforce events consistency across all the runtimes we support.

If there are no other arguments I'm leaning to close the PR. I will also deal with issue #273 because I'm convinced from the writing that the author was asking about managed persistent sessions, which aren't possible in Lambda OD.

I really appreciate your effort ❤️. If you find anything else you want to contribute to (we have a very long backlog and we welcome any external contribution) you can open a new issue or pick one of the existent ones. Just add some comments on what you want to do so I can give you advice on how to best deal with that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants